# -*- coding: utf-8 -*-
#
# The Philatelist program is a fork of the OpenNumismat program
# Copyright (c) 2011 - 2024 Vitaly Ignatov (OpenNumismat) <opennumismat@gmail.com>
# Copyright (c) 2021 - 2024 Victor Nabatov (Philatelist) <nabatov.victor@gmail.com>

import codecs
import json

from PySide6.QtCore import Qt
from PySide6.QtSql import QSqlQuery
from PySide6.QtWidgets import QApplication, QFileDialog, QMessageBox

from Philatelist.Collection.CollectionFields import CollectionFieldsBase, FieldTypes as Type
from Philatelist.Tools.Gui import ProgressDialog


class ExportToJson():

    def __init__(self, collection):
        self.collection = collection

    def exportToJson(self):
        text = QApplication.translate("Json", "Collection is not exported")
        file = self.collection.getFileName()
        json_file_name = '.json'.join(file.rsplit('.db', 1))
        json_file_name, _selectedFilter = QFileDialog.getSaveFileName(
            self.collection.parent(),
            QApplication.translate("Json", "Save as"),
            json_file_name,
            "*.json"
        )
        if json_file_name:
            model = self.collection.model()
            sort_column = model.fieldIndex('sort_id')
            model.setSort(sort_column, Qt.AscendingOrder)
            model.sort(sort_column, Qt.AscendingOrder)
            model.select()
            while model.canFetchMore():
                model.fetchMore()

            count = model.rowCount()
            json_file = codecs.open(json_file_name, "w", "utf-8")

            # Table "description"
            desc = self.collection.getDescription()
            data = {
                'title': desc.title,
                'description': desc.description,
                'author': desc.author,
                'type': "Philatelist",
                'count': count,
                'db_version': self.collection.settings['Version']
            }
            json_file.write('{"description": ')
            json.dump(
                data,
                json_file,
                indent=2,
                sort_keys=True,
                ensure_ascii=False
            )

            # Table "pages"
            json_file.write(',\n"pages": [\n')
            pages_count =  len(self.collection._pages.params)
            for position, param in enumerate(self.collection._pages.params):
                data = {
                    'id': param.id,
                    'title': param.title,
                    'isopen': param.isopen,
                    'position': position,
                    'type': param.type
                }
                json.dump(
                    data,
                    json_file,
                    indent=2,
                    sort_keys=False,
                    ensure_ascii=False
                )
                if position < pages_count - 1:
                    json_file.write(',\n')

            json_file.write('],\n')

            # Table "treeparam"
            sql = "SELECT MAX(id) FROM treeparam"
            query = QSqlQuery(sql, self.collection.db)
            query.exec_()

            if query.first():
                maxID = query.record().value(0)
                json_file.write('"treeparam": [\n')

                query = QSqlQuery(self.collection.db)
                query.prepare("SELECT * FROM treeparam")
                query.exec_()

                id = 0
                while query.next():
                    record = query.record()
                    data = {
                        'id': record.value('id'),
                        'pageid': record.value('pageid'),
                        'fieldid': record.value('fieldid'),
                        'position': record.value('position')
                    }
                    json.dump(
                        data,
                        json_file,
                        indent=2,
                        sort_keys=False,
                        ensure_ascii=False
                    )
                    id = id + 1
                    if id < maxID:
                        json_file.write(',\n')

                json_file.write('],\n')

            # Table "lists"
            sql = "SELECT MAX(id) FROM lists"
            query = QSqlQuery(sql, self.collection.db)
            query.exec_()

            if query.first():
                maxID = query.record().value(0)
                json_file.write('"lists": [\n')

                query = QSqlQuery(self.collection.db)
                query.prepare("SELECT * FROM lists")
                query.exec_()

                id = 0
                while query.next():
                    record = query.record()
                    data = {
                        'id': record.value('id'),
                        'pageid': record.value('pageid'),
                        'fieldid': record.value('fieldid'),
                        'position': record.value('position'),
                        'enabled': record.value('enabled'),
                        'width': record.value('width'),
                        'sortorder': record.value('sortorder'),
                    }
                    json.dump(
                        data,
                        json_file,
                        indent=2,
                        sort_keys=False,
                        ensure_ascii=False
                    )
                    id = id + 1
                    if id < maxID:
                        json_file.write(',\n')

                json_file.write('],\n')

            # Table "tags"
            sql = "SELECT MAX(id) FROM tags"
            query = QSqlQuery(sql, self.collection.db)
            query.exec_()

            if query.first():
                maxID = query.record().value(0)
                json_file.write('"tags": [\n')

                query = QSqlQuery(self.collection.db)
                query.prepare("SELECT * FROM tags")
                query.exec_()

                id = 0
                while query.next():
                    record = query.record()
                    data = {
                        'id': record.value('id'),
                        'tag': record.value('tag'),
                        'parent_id': record.value('parent_id'),
                        'position': record.value('position'),
                    }
                    json.dump(
                        data,
                        json_file,
                        indent=2,
                        sort_keys=False,
                        ensure_ascii=False
                    )
                    id = id + 1
                    if id < maxID:
                        json_file.write(',\n')

                json_file.write('],\n')

            # Table "stamps_tags"
            sql = "SELECT MAX(id) FROM stamps_tags"
            query = QSqlQuery(sql, self.collection.db)
            query.exec_()

            if query.first():
                maxID = query.record().value(0)
                json_file.write('"stamps_tags": [\n')

                query = QSqlQuery(self.collection.db)
                query.prepare("SELECT * FROM stamps_tags")
                query.exec_()

                id = 0
                while query.next():
                    record = query.record()
                    data = {
                        'id': record.value('id'),
                        'stamp_id': record.value('stamp_id'),
                        'tag_id': record.value('tag_id'),
                    }
                    json.dump(
                        data,
                        json_file,
                        indent=2,
                        sort_keys=False,
                        ensure_ascii=False
                    )
                    id = id + 1
                    if id < maxID:
                        json_file.write(',\n')

                json_file.write('],\n')

            # Table "stamps"
            json_file.write('"stamps": [\n')
            progressDlg = ProgressDialog(
                QApplication.translate("Json", "Exporting description, pages, tree, lists, tags"),
                QApplication.translate("Json", "Cancel"),
                count,
                self.collection.parent()
            )
            fields = CollectionFieldsBase()
            for i in range(count):
                data = {}
                stamp = model.record(i)
                for field in fields:
                    val = stamp.value(field.name)
                    if val is None or val == '':
                        continue

                    if field.name in ('id', 'create_date', 'update_date', 'sort_id') or field.type == Type.PreviewImage:
                        continue

                    if field.type == Type.Date and val == '2000-01-01':
                        continue

                    data[field.name] = val

                json.dump(
                    data,
                    json_file,
                    indent=2,
                    sort_keys=True,
                    ensure_ascii=False
                )
                progressDlg.step()
                if progressDlg.wasCanceled():
                    break

                if i < count - 1:
                    json_file.write(',\n')

            json_file.write(']\n}')
            json_file.close()
            progressDlg.reset()
            text = QApplication.translate("Json", "Exported %d stamp(s)") % (i + 1)

        QMessageBox.information(self.collection.parent(), QApplication.translate("Json", "Export"), text)
